local State = GLOBAL.State
local ActionHandler = GLOBAL.ActionHandler
local FRAMES = GLOBAL.FRAMES
local TimeEvent = GLOBAL.TimeEvent
local EventHandler = GLOBAL.EventHandler
local EQUIPSLOTS = GLOBAL.EQUIPSLOTS
local SpawnPrefab = GLOBAL.SpawnPrefab

local peer =
	State(
	{
		name = "musha_peertelescope",
		tags = {"doing", "busy", "canrotate", "notalking"},
		onenter = function(inst)
			local item = inst.components.inventory:GetEquippedItem(EQUIPSLOTS.HANDS)
			if item and item.components.equippable then
				item.components.equippable:Unequip(inst)
			end
			inst:ForceFacePoint(inst.x, inst.y, inst.z)
			inst.components.playercontroller:Enable(false)
			inst.components.health:SetInvincible(true)
			inst.components.locomotor:Stop()
			inst.AnimState:OverrideSymbol("swap_object", "musha_telescope_swap", "swap_object")
			inst.AnimState:Show("ARM_carry")
			inst.AnimState:Hide("ARM_normal")

			inst.AnimState:PlayAnimation("telescope", false)
			inst.AnimState:PushAnimation("telescope_pst", false)
		end,
		timeline = {
			TimeEvent(
				2 * FRAMES,
				function(inst)
					inst.SoundEmitter:PlaySound("dontstarve/wilson/equip_item_gold")
				end
			),
			TimeEvent(
				20 * FRAMES,
				function(inst)
					inst.SoundEmitter:PlaySound("dontstarve/creatures/smallbird/blink")
				end
			)
		},
		onexit = function(inst)
			inst.components.playercontroller:Enable(true)
			inst.components.health:SetInvincible(false)
			if inst.components.inventory:GetEquippedItem(EQUIPSLOTS.HANDS) then
				inst.AnimState:Show("ARM_carry")
				inst.AnimState:Hide("ARM_normal")
			else
				inst.AnimState:Hide("ARM_carry")
				inst.AnimState:Show("ARM_normal")
			end
		end,
		events = {
			EventHandler(
				"animover",
				function(inst)
					inst:PerformBufferedAction()
				end
			),
			EventHandler(
				"animqueueover",
				function(inst)
					inst.sg:GoToState("idle")
				end
			)
		}
	}
)
AddStategraphState("wilson", peer)

local musha_map =
	State(
	{
		name = "musha_map",
		tags = {"doing", "notalking"},
		onenter = function(inst)
			inst.components.playercontroller:Enable(false)
			inst.components.health:SetInvincible(true)
			inst.components.locomotor:Stop()
			inst.AnimState:PlayAnimation("scroll", false)
			inst.AnimState:OverrideSymbol("scroll", "musha_mapbottle", "scroll")
			inst.AnimState:PushAnimation("scroll_pst", false)

			--inst.AnimState:Hide("ARM_carry")
			inst.AnimState:Show("ARM_normal")
			if inst.components.inventory.activeitem and inst.components.inventory.activeitem.components.book then
				inst.components.inventory:ReturnActiveItem()
			end
		end,
		onexit = function(inst)
			inst.components.playercontroller:Enable(true)
			inst.components.health:SetInvincible(false)
			if inst.components.inventory:GetEquippedItem(EQUIPSLOTS.HANDS) then
				inst.AnimState:Show("ARM_carry")
				inst.AnimState:Hide("ARM_normal")
			end
		end,
		timeline = {
			--TimeEvent(3*FRAMES, function(inst) inst.SoundEmitter:PlaySound("dontstarve/common/use_book") end)
			TimeEvent(
				24 * FRAMES,
				function(inst)
					inst.SoundEmitter:PlaySound("dontstarve/common/use_book_light")
				end
			),
			TimeEvent(
				58 * FRAMES,
				function(inst)
					inst.SoundEmitter:PlaySound("dontstarve/common/use_book_close")
				end
			)
		},
		events = {
			EventHandler(
				"animover",
				function(inst)
					inst:PerformBufferedAction()
				end
			),
			EventHandler(
				"animqueueover",
				function(inst)
					inst.sg:GoToState("idle")
				end
			)
		}
	}
)
AddStategraphState("wilson", musha_map)

local musha_bowm =
	State(
	{
		name = "blowdart",
		tags = {"attack", "notalking", "abouttoattack", "autopredict"},
		onenter = function(inst)
			inst.components.locomotor:Stop()
			local buffaction = inst:GetBufferedAction()
			local target = buffaction ~= nil and buffaction.target or nil

			inst.components.combat:SetTarget(target)
			inst.components.combat:StartAttack()
			local cooldown = math.max(inst.components.combat.min_attack_period + .5 * FRAMES, 20 * FRAMES)

			--local weapon = inst.components.combat ~= nil and inst.components.combat:GetWeapon() or nil
			local weapon = inst.components.inventory:GetEquippedItem(EQUIPSLOTS.HANDS)
			if weapon and weapon:HasTag("musha_bowm") then
				inst.AnimState:OverrideSymbol("swap_object", "musha_bowm_ready_swap", "musha_bowm")
				inst.AnimState:PlayAnimation("speargun")
			else
				inst.AnimState:PlayAnimation("dart")
			end

			inst.sg:SetTimeout(cooldown)

			if target ~= nil and target:IsValid() then
				inst:FacePoint(target.Transform:GetWorldPosition())
				inst.sg.statemem.attacktarget = target
			end
		end,
		timeline = {
			TimeEvent(
				8 * FRAMES,
				function(inst)
					local weapon = inst.components.inventory:GetEquippedItem(EQUIPSLOTS.HANDS)
					if weapon and weapon:HasTag("musha_bowm") then
					else
						inst.SoundEmitter:PlaySound("dontstarve/wilson/blowdart_shoot", nil, nil, true)
					end
				end
			),
			TimeEvent(
				10 * FRAMES,
				function(inst)
					inst:PerformBufferedAction()
					inst.sg:RemoveStateTag("abouttoattack")
					local weapon = inst.components.inventory:GetEquippedItem(EQUIPSLOTS.HANDS)
					if weapon and weapon:HasTag("musha_bowm") then
						if math.random() < 0.55 then
							inst.SoundEmitter:PlaySound("musha_bowm/musha/musha_bowm/bow", nil, nil, true)
						else
							inst.SoundEmitter:PlaySound("musha_bowm/musha/musha_bowm/bow2", nil, nil, true)
						end
					else
						inst.SoundEmitter:PlaySound("dontstarve/wilson/blowdart_shoot", nil, nil, true)
					end
				end
			)
		},
		ontimeout = function(inst)
			inst.sg:RemoveStateTag("attack")
			inst.sg:AddStateTag("idle")
		end,
		events = {
			EventHandler(
				"equip",
				function(inst)
					inst.sg:GoToState("idle")
				end
			),
			EventHandler(
				"unequip",
				function(inst)
					inst.sg:GoToState("idle")
				end
			),
			EventHandler(
				"animover",
				function(inst)
					if inst.AnimState:AnimDone() then
						inst.sg:GoToState("idle")
					end
				end
			)
		},
		onexit = function(inst)
			inst.components.combat:SetTarget(nil)
			if inst.sg:HasStateTag("abouttoattack") then
				inst.components.combat:CancelAttack()
			end

			--[[ local weapon = inst.components.combat and inst.components.combat:GetWeapon()
		if weapon and weapon:HasTag("musha_bowm") then
			inst.AnimState:OverrideSymbol("swap_object", "musha_bowm_boost_swap", "musha_bowm")
		elseif weapon and not weapon:HasTag("musha_bowm") and weapon:HasTag("musha_items") and not weapon.broken then
			inst.AnimState:OverrideSymbol("swap_object", "musha_bowm_swap", "musha_bowm")
		elseif weapon and not weapon:HasTag("musha_bowm") and weapon:HasTag("musha_items") and weapon.broken then
			inst.AnimState:OverrideSymbol("swap_object", "musha_bowm_broken_swap", "musha_bowm")
		end ]]
		end
	}
)
AddStategraphState("wilson", musha_bowm)

local musha_bowm_c =
	State(
	{
		name = "blowdart",
		tags = {"attack", "notalking", "abouttoattack"},
		onenter = function(inst)
			local equip = inst.replica.inventory:GetEquippedItem(EQUIPSLOTS.HANDS)
			inst.components.locomotor:Stop()

			inst.AnimState:PlayAnimation("dart_pre")
			if inst.sg.laststate == inst.sg.currentstate then
				inst.sg.statemem.chained = true
				inst.AnimState:SetTime(5 * FRAMES)
			end
			local weapon = inst.replica.inventory:GetEquippedItem(EQUIPSLOTS.HANDS)
			if weapon and weapon:HasTag("musha_bowm") then
				inst.AnimState:OverrideSymbol("swap_object", "musha_bowm_ready_swap", "musha_bowm")
				inst.AnimState:PlayAnimation("speargun")
			else
				inst.AnimState:PushAnimation("dart", false)
			end

			if inst.replica.combat ~= nil then
				inst.replica.combat:StartAttack()
				inst.sg:SetTimeout(
					math.max((inst.sg.statemem.chained and 14 or 18) * FRAMES, inst.replica.combat:MinAttackPeriod() + .5 * FRAMES)
				)
			end

			local buffaction = inst:GetBufferedAction()
			if buffaction ~= nil then
				inst:PerformPreviewBufferedAction()

				if buffaction.target ~= nil and buffaction.target:IsValid() then
					inst:FacePoint(buffaction.target:GetPosition())
					inst.sg.statemem.attacktarget = buffaction.target
				end
			end

			if (equip.projectiledelay or 0) > 0 then
				--V2C: Projectiles don't show in the initial delayed frames so that
				--     when they do appear, they're already in front of the player.
				--     Start the attack early to keep animation in sync.
				inst.sg.statemem.projectiledelay = (inst.sg.statemem.chained and 9 or 14) * FRAMES - equip.projectiledelay
				if inst.sg.statemem.projectiledelay <= 0 then
					inst.sg.statemem.projectiledelay = nil
				end
			end
		end,
		onupdate = function(inst, dt)
			if (inst.sg.statemem.projectiledelay or 0) > 0 then
				inst.sg.statemem.projectiledelay = inst.sg.statemem.projectiledelay - dt
				if inst.sg.statemem.projectiledelay <= 0 then
					inst:ClearBufferedAction()
					inst.sg:RemoveStateTag("abouttoattack")
				end
			end
		end,
		timeline = {
			TimeEvent(
				8 * FRAMES,
				function(inst)
					if inst.sg.statemem.chained then
						inst.SoundEmitter:PlaySound("dontstarve/wilson/blowdart_shoot", nil, nil, true)
					end
				end
			),
			TimeEvent(
				9 * FRAMES,
				function(inst)
					if inst.sg.statemem.chained and inst.sg.statemem.projectiledelay == nil then
						inst:ClearBufferedAction()
						inst.sg:RemoveStateTag("abouttoattack")
					end
				end
			),
			TimeEvent(
				13 * FRAMES,
				function(inst)
					local weapon = inst.replica.inventory:GetEquippedItem(EQUIPSLOTS.HANDS)
					if weapon and weapon:HasTag("musha_bowm") then
						if math.random() < 0.55 then
							inst.SoundEmitter:PlaySound("musha_bowm/musha/musha_bowm/bow", nil, nil, true)
						else
							inst.SoundEmitter:PlaySound("musha_bowm/musha/musha_bowm/bow2", nil, nil, true)
						end
					elseif not inst.sg.statemem.chained then
						inst.SoundEmitter:PlaySound("dontstarve/wilson/blowdart_shoot", nil, nil, true)
					end
				end
			),
			TimeEvent(
				14 * FRAMES,
				function(inst)
					if not inst.sg.statemem.chained and inst.sg.statemem.projectiledelay == nil then
						inst:ClearBufferedAction()
						inst.sg:RemoveStateTag("abouttoattack")
					end
				end
			)
		},
		ontimeout = function(inst)
			inst.sg:RemoveStateTag("attack")
			inst.sg:AddStateTag("idle")
		end,
		events = {
			EventHandler(
				"animqueueover",
				function(inst)
					if inst.AnimState:AnimDone() then
						inst.sg:GoToState("idle")
					end
				end
			)
		},
		onexit = function(inst)
			if inst.sg:HasStateTag("abouttoattack") and inst.replica.combat ~= nil then
				inst.replica.combat:CancelAttack()
			end
			--[[ local weapon = inst.replica.inventory:GetEquippedItem(EQUIPSLOTS.HANDS)
		if weapon and weapon:HasTag("musha_bowm") then
			inst.AnimState:OverrideSymbol("swap_object", "musha_bowm_boost_swap", "musha_bowm")
		elseif weapon and not weapon:HasTag("musha_bowm") and weapon:HasTag("musha_items") and not weapon.broken then
			inst.AnimState:OverrideSymbol("swap_object", "musha_bowm_swap", "musha_bowm")
		elseif weapon and not weapon:HasTag("musha_bowm") and weapon:HasTag("musha_items") and weapon.broken then
			inst.AnimState:OverrideSymbol("swap_object", "musha_bowm_broken_swap", "musha_bowm")
		end ]]
		end
	}
)
AddStategraphState("wilson_client", musha_bowm_c)

AddStategraphState(
	"wilson",
	State(
		{
			name = "musha_powerattack",
			tags = {"attack", "notalking", "abouttoattack", "autopredict", "doing"},
			onenter = function(inst)
				local buffaction = inst:GetBufferedAction()
				local target = buffaction ~= nil and buffaction.target or nil
				inst.components.combat:SetTarget(target)
				inst.components.combat:StartAttack()
				inst.components.locomotor:Stop()
				local cooldown = inst.components.combat.min_attack_period + .5 * FRAMES
				inst.AnimState:PushAnimation("pickaxe_loop", false)
				local weapon = inst.components.combat ~= nil and inst.components.combat:GetWeapon() or nil
				if weapon and weapon.prefab == "musha_phoenixaxe" then
					inst.SoundEmitter:PlaySound("dontstarve/wilson/attack_firestaff", nil, nil, true)
				else
					inst.SoundEmitter:PlaySound("dontstarve/wilson/attack_icestaff", nil, nil, true)
				end
				inst.sg:SetTimeout(math.max(cooldown, 13 * FRAMES))

				if target ~= nil then
					inst.components.combat:BattleCry()
					if target:IsValid() then
						inst:FacePoint(target:GetPosition())
						inst.sg.statemem.attacktarget = target
					end
				end
			end,
			timeline = {
				TimeEvent(
					10 * FRAMES,
					function(inst)
						inst:PerformBufferedAction()
						inst.sg:RemoveStateTag("abouttoattack")
					end
				)
			},
			ontimeout = function(inst)
				inst.sg:RemoveStateTag("attack")
				inst.sg:AddStateTag("idle")
				if inst.bufferedaction == inst.sg.statemem.action then
					inst:ClearBufferedAction()
				end
				inst.sg.statemem.action = nil
			end,
			events = {
				EventHandler(
					"equip",
					function(inst)
						inst.sg:GoToState("idle")
					end
				),
				EventHandler(
					"unequip",
					function(inst)
						inst.sg:GoToState("idle")
					end
				),
				EventHandler(
					"animqueueover",
					function(inst)
						if inst.AnimState:AnimDone() then
							inst.AnimState:PlayAnimation("pickaxe_pst")
							inst.sg:GoToState("idle", true)
						end
					end
				)
			},
			onexit = function(inst)
				inst.components.combat:SetTarget(nil)
				if inst.sg:HasStateTag("abouttoattack") then
					inst.components.combat:CancelAttack()
				end
				if inst.bufferedaction == inst.sg.statemem.action then
					inst:ClearBufferedAction()
				end
				inst.sg.statemem.action = nil
			end
		}
	)
)
AddStategraphState(
	"wilson_client",
	State(
		{
			name = "musha_powerattack",
			tags = {"attack", "notalking", "abouttoattack", "autopredict", "doing"},
			onenter = function(inst)
				local cooldown = inst.replica.combat:MinAttackPeriod() + .5 * FRAMES
				if inst.replica.combat ~= nil then
					inst.replica.combat:StartAttack()
				end
				inst.components.locomotor:Stop()
				inst.AnimState:PlayAnimation("pickaxe_loop", false)
				local weapon = inst.replica.inventory:GetEquippedItem(EQUIPSLOTS.HANDS)
				if weapon and weapon.prefab == "musha_phoenixaxe" then
					inst.SoundEmitter:PlaySound("dontstarve/wilson/attack_firestaff", nil, nil, true)
				else
					inst.SoundEmitter:PlaySound("dontstarve/wilson/attack_icestaff", nil, nil, true)
				end
				if cooldown > 0 then
					cooldown = math.max(cooldown, 13 * FRAMES)
				end
				if inst.components.playercontroller then
					inst.components.playercontroller:Enable(false)
				end

				inst:PerformPreviewBufferedAction()

				local buffaction = inst:GetBufferedAction()
				if buffaction ~= nil then
					inst:PerformPreviewBufferedAction()
					if buffaction.target ~= nil and buffaction.target:IsValid() then
						inst:FacePoint(buffaction.target:GetPosition())
						inst.sg.statemem.attacktarget = buffaction.target
					end
				end

				if cooldown > 0 then
					inst.sg:SetTimeout(cooldown)
				end
			end,
			timeline = {
				TimeEvent(
					10 * FRAMES,
					function(inst)
						inst:ClearBufferedAction()
						inst.sg:RemoveStateTag("abouttoattack")
					end
				)
			},
			ontimeout = function(inst)
				inst:ClearBufferedAction()
				inst.sg:RemoveStateTag("attack")
				inst.sg:AddStateTag("idle")
				if inst.bufferedaction == inst.sg.statemem.action then
					inst:ClearBufferedAction()
				end
				inst.sg.statemem.action = nil
			end,
			events = {
				EventHandler(
					"animqueueover",
					function(inst)
						if inst.AnimState:AnimDone() then
							inst.AnimState:PlayAnimation("pickaxe_pst")
							--inst.AnimState:PushAnimation("pickaxe_lag", false)
							inst.sg:GoToState("idle", true)
						end
					end
				)
			},
			onexit = function(inst)
				if inst.sg:HasStateTag("abouttoattack") and inst.replica.combat ~= nil then
					inst.replica.combat:CancelAttack()
				end
				if inst.bufferedaction == inst.sg.statemem.action then
					inst:ClearBufferedAction()
				end
				inst.sg.statemem.action = nil
			end
		}
	)
)

AddStategraphState(
	"wilson",
	State(
		{
			name = "musha_powerattack_pre",
			tags = {"attack", "notalking", "abouttoattack", "autopredict", "doing", "busy"},
			onenter = function(inst)
				local buffaction = inst:GetBufferedAction()
				local target = buffaction ~= nil and buffaction.target or nil
				if
					target and (target.components.health and not target.components.health:IsDead()) and
						(inst.components.health and not inst.components.health:IsDead()) and
						inst.components.musha_spellpower:CanCost(inst.components.musha_skills.skilldata("PowerAttack", "spellpowercost"))
				 then
					inst.components.health:SetInvincible(true)
					--inst.SoundEmitter:PlaySound("dontstarinste/creatures/chester/raise")
					local fx = SpawnPrefab("musha_forcefieldx")
					fx.entity:SetParent(inst.entity)
					if inst.components.rider ~= nil and inst.components.rider:IsRiding() then
						fx.Transform:SetScale(2, 2, 2)
					else
						fx.Transform:SetScale(0.8, 0.8, 0.8)
					end
					fx.Transform:SetPosition(0, 0.2, 0)
					local fx_hitanim = function()
						fx.AnimState:PlayAnimation("hit")
						fx.AnimState:PushAnimation("idle_loop")
					end
					fx:ListenForEvent("blocked", fx_hitanim, inst)
					inst:DoTaskInTime(
						inst.components.musha_skills.skilldata("PowerAttack", "shieldtime"),
						function()
							fx:RemoveEventCallback("blocked", fx_hitanim, inst)
							inst.components.health:SetInvincible(false)
							if inst.components.musha_skills.skill_point["FireShield"]:value() == 5 then
								inst.components.musha_skills:refreshfireshield()
							end
							if inst:IsValid() then
								fx.kill_fx(fx)
							end
						end
					)
					inst.components.combat:SetTarget(target)
					inst.components.combat:StartAttack()
					if target ~= nil and target.components.locomotor then
						target.components.locomotor:Stop()
					end
					inst.components.locomotor:Stop()
					--inst.SoundEmitter:PlaySound("dontstarve/wilson/attack_weapon")
					inst.AnimState:PlayAnimation("pickaxe_pre")
				else
					inst.sg:GoToState("mindcontrolled")
				end
				inst.SoundEmitter:PlaySound("dontstarve/wilson/attack_icestaff")
				inst:PerformPreviewBufferedAction()
			end,
			timeline = {},
			events = {
				EventHandler(
					"unequip",
					function(inst)
						inst:ClearBufferedAction()
						inst.AnimState:PlayAnimation("pickaxe_pst")
						inst.AnimState:PushAnimation("pickaxe_lag", false)
						inst.sg:GoToState("idle", true)
					end
				),
				EventHandler(
					"animover",
					function(inst)
						if inst.AnimState:AnimDone() then
							inst.sg:RemoveStateTag("abouttoattack")
							inst.sg:GoToState("musha_powerattack")
						end
					end
				)
			},
			onexit = function(inst)
				inst.components.combat:SetTarget(nil)
				if inst.sg:HasStateTag("abouttoattack") then
					inst.components.combat:CancelAttack()
				end
			end
		}
	)
)
AddStategraphState(
	"wilson_client",
	State(
		{
			name = "musha_powerattack_pre",
			tags = {"attack", "notalking", "abouttoattack", "autopredict", "doing", "busy"},
			onenter = function(inst)
				--inst.replica.combat:SetTarget(target)
				--inst.replica.combat:StartAttack()
				local cooldown = inst.replica.combat:MinAttackPeriod() + .5 * FRAMES
				if inst.replica.combat ~= nil then
					inst.replica.combat:StartAttack()
				end
				inst.components.locomotor:Stop()
				--inst.SoundEmitter:PlaySound("dontstarve/wilson/attack_weapon")
				inst.AnimState:PlayAnimation("pickaxe_pre")
				--inst.AnimState:PushAnimation("pickaxe_lag", false)
				cooldown = math.max(cooldown, 6 * FRAMES)
				inst.SoundEmitter:PlaySound("dontstarve/wilson/attack_icestaff")
				--inst.sg:SetTimeout(cooldown)
				inst:PerformPreviewBufferedAction()
			end,
			timeline = {},
			events = {
				EventHandler(
					"unequip",
					function(inst)
						inst:ClearBufferedAction()
						inst.AnimState:PlayAnimation("pickaxe_pst")
						inst.AnimState:PushAnimation("pickaxe_lag", false)
						inst.sg:GoToState("idle", true)
					end
				),
				EventHandler(
					"animover",
					function(inst)
						if inst.AnimState:AnimDone() then
							inst.sg:RemoveStateTag("abouttoattack")
							inst.sg:GoToState("musha_powerattack")
						end
					end
				)
			},
			onexit = function(inst)
				if inst.sg:HasStateTag("abouttoattack") and inst.replica.combat ~= nil then
					inst.replica.combat:CancelAttack()
				end
			end
		}
	)
)

AddStategraphActionHandler("wilson", ActionHandler(ACTIONS.Musha_PowerAttack, "musha_powerattack_pre"))
AddStategraphActionHandler("wilson_client", ActionHandler(ACTIONS.Musha_PowerAttack, "musha_powerattack_pre"))

AddStategraphState(
	"wilson",
	State(
		{
			name = "Musha_Electric_Book",
			tags = {"doing", "busy", "notalking"},
			onenter = function(inst)
				inst.components.locomotor:Stop()

				if inst.components.musha_spellpower and inst.components.musha_spellpower.current > 20 then
					inst.AnimState:PlayAnimation("action_uniqueitem_pre")
					inst.AnimState:PushAnimation("book", true)
				else
					inst.sg:GoToState("mindcontrolled")
				end

				inst.AnimState:Show("ARM_normal")
				inst.components.inventory:ReturnActiveActionItem(
					inst.bufferedaction ~= nil and (inst.bufferedaction.target or inst.bufferedaction.invobject) or nil
				)
				inst.sg:SetTimeout(3)
			end,
			timeline = {
				TimeEvent(
					0,
					function(inst)
						local fxtoplay =
							inst.components.rider ~= nil and inst.components.rider:IsRiding() and "book_fx_mount" or "book_fx"
						local fx = SpawnPrefab(fxtoplay)
						fx.entity:SetParent(inst.entity)
						fx.Transform:SetPosition(0, 0.2, 0)
						inst.sg.statemem.book_fx = fx
					end
				),
				TimeEvent(
					28 * FRAMES,
					function(inst)
						local fx_1 = SpawnPrefab("musha_shadowshield")
						fx_1.Transform:SetScale(0.5, 0.5, 0.5)
						fx_1.Transform:SetPosition(inst:GetPosition():Get())
						inst.SoundEmitter:PlaySound("dontstarve/common/use_book_light")
					end
				),
				TimeEvent(
					54 * FRAMES,
					function(inst)
						inst.SoundEmitter:PlaySound("dontstarve/common/use_book_close")
						inst.sg:RemoveStateTag("busy")
					end
				),
				TimeEvent(
					58 * FRAMES,
					function(inst)
						inst.SoundEmitter:PlaySound("dontstarve/common/book_spell")
						inst:PerformBufferedAction()
						inst.sg.statemem.book_fx = nil
					end
				)
			},
			events = {
				EventHandler(
					"animqueueover",
					function(inst)
						if inst.AnimState:AnimDone() then
							inst.sg:GoToState("idle")
						end
					end
				)
			},
			ontimeout = function(inst)
				inst.sg:RemoveStateTag("doing")
				inst.sg:RemoveStateTag("notalking")
				inst:ClearBufferedAction()

				if inst.AnimState:AnimDone() then
					inst.sg:GoToState("idle")
				end
			end,
			onexit = function(inst)
				if inst.components.inventory:GetEquippedItem(EQUIPSLOTS.HANDS) then
					inst.AnimState:Hide("ARM_normal")
					inst.AnimState:Show("ARM_carry")
				end
				if inst.sg.statemem.book_fx then
					inst.sg.statemem.book_fx:Remove()
					inst.sg.statemem.book_fx = nil
				end
				if inst.bufferedaction == inst.sg.statemem.action then
					inst:ClearBufferedAction()
				end
				inst.sg.statemem.action = nil
			end
		}
	)
)
AddStategraphState(
	"wilson_client",
	State(
		{
			name = "Musha_Electric_Book",
			tags = {"doing", "busy", "notalking"},
			onenter = function(inst)
				--if inst.components.playercontroller then
				--	inst.components.playercontroller:Enable(false)
				--end
				if inst.replica.health then
				--inst.replica.health:SetInvincible(true)
				end
				inst.components.locomotor:Stop()
				-------- --------
				inst.AnimState:PlayAnimation("action_uniqueitem_pre")
				inst.AnimState:PushAnimation("action_uniqueitem_lag", false)
				--inst.AnimState:PushAnimation("book", false)
				inst:PerformPreviewBufferedAction()
				inst.sg:SetTimeout(2.5)
			end,
			timeline = {
				TimeEvent(
					0,
					function(inst)
						local fxtoplay = inst.replica.rider ~= nil and inst.replica.rider:IsRiding() and "book_fx_mount" or "book_fx"
						local fx = SpawnPrefab(fxtoplay)
						fx.entity:SetParent(inst.entity)
						fx.Transform:SetPosition(0, 0.2, 0)
						inst.sg.statemem.book_fx = fx
					end
				),
				TimeEvent(
					28 * FRAMES,
					function(inst)
						inst.SoundEmitter:PlaySound("dontstarve/common/use_book_light")
					end
				),
				TimeEvent(
					54 * FRAMES,
					function(inst)
						inst.SoundEmitter:PlaySound("dontstarve/common/use_book_close")
						inst.sg:RemoveStateTag("busy")
					end
				),
				TimeEvent(
					58 * FRAMES,
					function(inst)
						inst.SoundEmitter:PlaySound("dontstarve/common/book_spell")
						inst:PerformBufferedAction()
						inst.sg.statemem.book_fx = nil
					end
				)
			},
			events = {
				EventHandler(
					"animqueueover",
					function(inst)
						if inst.AnimState:AnimDone() then
							inst.sg:GoToState("idle")
						end
					end
				)
			},
			onupdate = function(inst)
				if inst:HasTag("doing") then
					if inst.entity:FlattenMovementPrediction() then
						inst.sg:GoToState("idle", "noanim")
					end
				elseif inst.bufferedaction == nil then
					inst.sg:GoToState("idle")
				end
			end,
			ontimeout = function(inst)
				inst:ClearBufferedAction()
				if inst.AnimState:AnimDone() then
					inst.sg:GoToState("idle")
				end
			end,
			onexit = function(inst)
				--inst.components.playercontroller:Enable(true)
				if inst.replica.inventory:GetEquippedItem(EQUIPSLOTS.HANDS) then
					inst.AnimState:Show("ARM_carry")
					inst.AnimState:Hide("ARM_normal")
				end
				if inst.sg.statemem.book_fx then
					inst.sg.statemem.book_fx:Remove()
					inst.sg.statemem.book_fx = nil
				end
				if inst.bufferedaction == inst.sg.statemem.action then
					inst:ClearBufferedAction()
				end
				inst.sg.statemem.action = nil
			end
		}
	)
)
AddStategraphActionHandler("wilson", ActionHandler(ACTIONS.Musha_ElectricBook, "Musha_Electric_Book"))
AddStategraphActionHandler("wilson_client", ActionHandler(ACTIONS.Musha_ElectricBook, "Musha_Electric_Book"))

AddStategraphActionHandler("wilson", ActionHandler(ACTIONS.Musha_REPAIR, "dolongaction"))
AddStategraphActionHandler("wilson_client", ActionHandler(ACTIONS.Musha_REPAIR, "dolongaction"))
